package pl.edu.agh.student.logic.webapp;

import java.io.Serializable;
import java.util.LinkedList;
import java.util.List;

import javax.ejb.Remove;
import javax.ejb.Stateful;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Destroy;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Out;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.Transactional;
import org.jboss.seam.log.Log;
import org.jboss.seam.security.Identity;
import org.jbpm.api.HistoryService;
import org.jbpm.api.TaskService;
import org.jbpm.api.history.HistoryTask;
import org.jbpm.api.task.Task;

import pl.edu.agh.student.logic.service.ApplicationServiceImpl;
import pl.edu.agh.student.logic.service.UserServiceImpl;
import pl.edu.agh.student.logic.util.ServiceProvider;
import pl.edu.agh.student.model.Application;
import pl.edu.agh.student.model.Attachment;
import pl.edu.agh.student.model.Role;
import pl.edu.agh.student.model.User;

/**
 *
 * @author janburkot
 */
@Stateful
@Name("taskBean")
@Scope(ScopeType.CONVERSATION)
@Transactional
public class TaskBeanImpl implements TaskBean, Serializable {

    @In("serviceProvider")
    protected ServiceProvider serviceProvider;
    
    @In(value="userService",create=true,required=false)
    @Out
    protected UserServiceImpl userService;
    
    @In
    Identity identity;
    
    @Logger
    protected Log log;
    
    @In(value="applicationService",create=true,required=false)
    @Out
    protected ApplicationServiceImpl applicationService;
    
    private Application currentApplication;
    private Task currentTask;
    private String taskId;
    
	public TaskBeanImpl() {
	}
    
    public List<Task> getAll() {
        TaskService taskService = serviceProvider.getTaskService();
        
        User user = userService.findByUsername(identity.getPrincipal().getName());
        List<Role> roles = new LinkedList<Role>();
        
        roles.addAll(user.getRoles());
        
        taskService.findGroupTasks(getJbpmGroup(roles.get(0).getName()));
        
        List<Task> tasks = taskService.createTaskQuery().list();
        System.out.println(tasks);
        return tasks;
    }
    
    @Destroy
    @Remove
    public void destroy() {
        log.debug("destry component #0", this);
    }
    
    private String getJbpmGroup(String role){
        if("Szef".equals(role)){
            return "boss-group";
        }
        else if("Analityk".equals("role")){
            return "analyst-group";
        }
        else if("Klient".equals("role")){
            return "customer-group";
        }
        else{
            return null;
        }
        
    }

    public String take(Task task) {
        System.out.println("=-=-=-=-=-=-=-=-");
        System.out.println(identity.getPrincipal().getName());
        System.out.println(task.getId());
        
        
        TaskService taskService = serviceProvider.getTaskService();
        
        List<Task> ts = taskService.findGroupTasks(identity.getPrincipal().getName());
        
        boolean can = false;
        for(Task t: ts){
            if(task.getId().equals(t.getId())){
                can = true;
            }
        }
        
        if(can){
            taskService.takeTask(task.getId(), identity.getPrincipal().getName());
        }
        
        return "success";
    }

    public String complete(Task task, String action) {
        System.out.println("complete("+task+"."+task.getId()+", "+action+")");
        TaskService taskService = serviceProvider.getTaskService();
        taskService.completeTask(task.getId(), action);
        taskId = null;
        currentTask = null;
        
//        System.out.println("_+_+_+_+_+_+_+_+_+_+_+_+");
        return "success";
    }

    public List<Task> getInState(String stateName) {
        TaskService taskService = serviceProvider.getTaskService();
        List<Task> tasks = taskService.createTaskQuery().activityName(stateName).assignee(identity.getPrincipal().getName()).list();
//        System.out.println(tasks);
//        for(Task t: tasks){
//            System.err.println(t);
//            System.err.println(taskService.getVariableNames(t.getId()));
//            for(String s: taskService.getVariableNames(t.getId())){
//                System.err.println(s+" = "+taskService.getVariable(t.getId(), s));
//            }
//        }
        return tasks;
    }

    public List<HistoryTask> getHistoryTask(String executionId) {
        HistoryService historyService = serviceProvider.getHistoryService();
        return historyService.createHistoryTaskQuery().executionId(executionId).list();
    }

    public Application getApplication(Task task) {
        //TODO optymalizacja by zmiejszyc ilosc zapytan
        TaskService taskService = serviceProvider.getTaskService();
        Long applicationId = (Long)taskService.getVariable(task.getId(), "applicationId");
        currentApplication = applicationService.find(applicationId);
        
        return currentApplication;
    }

    public void setSelectedTask(Task task) {
        System.out.println("setSelectedTask");
        System.out.println(task);
        System.out.println(task.getId());
        this.taskId = task.getId();
    }

    public Task getCurrentTask() {
        System.out.println("getCurrentTask");
        if(taskId != null){      
            TaskService taskService = serviceProvider.getTaskService();
            currentTask = taskService.getTask(taskId);
            List<Task> l = taskService.createTaskQuery().list();

            System.out.println("currentTask"+currentTask);
            System.out.println("currentTask"+currentTask.getId());
        }
        
        return currentTask; 
    }    
    
    public List<Attachment> getFiles() {
        System.out.println("getFiles()"); 
        List<Attachment> files = new LinkedList<Attachment>();
        Task task = getCurrentTask();
        Application application = getApplication(task);
        files.addAll(application.getAttachments());
        return files;
    }
}
